package xiaoa.java.netty;

import java.net.URI;


import java.util.Map;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.HttpRequest;

/**
 * 简单http请求
 * @author xiaoa
 * @date 2017年8月18日 下午11:06:39
 * @version V1.0
 *
 */
public class SimpleHttpClient extends HttpClient {

	/**
	 * 管理工具
	 */
	private  Bootstrap  boot = null;
	

	public SimpleHttpClient(){
		
		this(30 * 1000);
	}
	

	/**
	 * 
	 * 构造器
	 * <p>Title: </p>
	 * <p>Description: </p>
	 * @author xiaoa
	 * @param connTimeOut  连接超时时间
	 */
	public SimpleHttpClient(int connTimeOut){

		this.boot = initBootstrap( connTimeOut);
	}
	
	/**
	 * 初始化
	 * @Title: initBootstrap
	 * @param connTimeOut
	 * @return
	 * @author xiaoa
	 */
	protected Bootstrap initBootstrap(int connTimeOut){
		
		Bootstrap boot = new Bootstrap();
		
		// 绑定管理分组
		boot.group(new NioEventLoopGroup());
	    boot.channel(NioSocketChannel.class)
	   .option(ChannelOption.TCP_NODELAY, true)
	   .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connTimeOut > 0 ? connTimeOut : 30 * 1000);
	    
		boot.handler(new ChannelInitializer<NioSocketChannel>() {

			@Override
			protected void initChannel(NioSocketChannel arg0) throws Exception {
				
				// 初始化
				initFillHandler(arg0.pipeline());
				
			}
		});
		
		return boot;
	}
	
	

	
	
	@Override
	public HttpResponseResult doRequest(HttpRequest request) throws Exception {
		
		return doRequest(request, 0 );
	}

	@Override
	public HttpResponseResult doRequest(HttpRequest request, int socketTimeOut) throws Exception {
		
		return doRequest(request, socketTimeOut);
	}

	
    /**
     * 发起请求
     */
	@Override
	public HttpResponseResult doRequest(final HttpRequest request, final int socketTimeOut ,final Map<String, String> handerMap) throws Exception {
		
		
		if (request == null ){
			throw new RuntimeException(" request is null");
		}
		
		final URI uri =  new URI(request.uri());
		
		if (uri == null || uri.toString().isEmpty()){
			throw new RuntimeException(" uri is null");
		}
	
		int port = getPort(uri);
		
		ChannelFuture fu =  boot.connect(uri.getHost(), port);
		
		return doPutReuqest(fu, request, socketTimeOut, handerMap);
	
	}
	

	@Override
	public HttpResponseResult doRequest(HttpRequest request, Map<String, String> handerMap) throws Exception {
		
		
		long startTime = System.currentTimeMillis();
		
		try {
		      return doRequest(request, 0, handerMap);
		}finally{
			Log.info(" url = " + request.uri() + "  useTime = " + (System.currentTimeMillis() - startTime));

		}
		
	}


	@Override
	public void release(Channel channel, URI url) throws Exception {
		channel.close();
	}

	@Override
	void releaseAndClose(Channel channel, URI uri) throws Exception {
		release(channel , uri);
	}


}
